home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 7 / Gekikoh Dennoh Club Vol. 7 (Japan).7z / Gekikoh Dennoh Club Vol. 7 (Japan) (Track 01).bin / games / otoko / source.lzh / eshot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-14  |  5.8 KB  |  236 lines

  1. #include <xsp2lib.h>
  2.  
  3. #include "otoko.h"
  4. #include "player.h"
  5. #include "eshot.h"
  6. #include "priority.h"
  7.  
  8. #ifndef NULL
  9. #define NULL ((void *) 0)
  10. #endif
  11.  
  12. #define    PALET_ESHOT    0x0300
  13.  
  14. #define ESHOT_MAX    200    /* 敵弾最大数 */
  15. static ESHOT eshot[ESHOT_MAX];    /* ワーク */
  16.  
  17.  
  18.  
  19. /* 起動時に1度だけ呼ばれる */
  20. void EshotInit0 (void)
  21. {
  22.     int i;
  23.  
  24.     /* リストをつなげる */
  25.     eshot_top = NULL;
  26.     eshot_null_top = eshot;
  27.     for (i = 0; i < ESHOT_MAX; i++)
  28.         eshot[i].next = &eshot[i + 1];
  29.  
  30.     eshot[ESHOT_MAX - 1].next = NULL;
  31.  
  32.     eshot_erase = 0;
  33. }
  34.  
  35.  
  36.  
  37. /* 敵弾出現時に呼ばれる */
  38. void EshotInit (short type, signed short x, signed short y, unsigned char speed, unsigned char angle, signed short t)
  39. {
  40.     ESHOT *p;
  41.  
  42.     if (eshot_null_top == NULL)    /* ワークの空きはあるか? */
  43.         return;
  44.  
  45.     p = eshot_null_top;
  46.     eshot_null_top = p->next;
  47.     p->next = eshot_top;
  48.     eshot_top = p;
  49.  
  50.     p->lx = (x - 8) << 16;    /* (8,8) がスプライト座標の中心なので補正 */
  51.     p->ly = (y - 8) << 16;
  52.     p->vx = vxtable[speed][angle];
  53.     p->vy = vytable[speed][angle];
  54.     if (t) {        /* t フレーム後の値を初期値に */
  55.         p->lx += (p->vx * t);
  56.         p->ly += (p->vy * t);
  57.     }
  58.     /* メモ:敵弾の速度と当り判定の大きさについて */
  59.     /* eshot->hx が以下の場合、eshot->vx の最大値は以下の通り */
  60.     /* (hx,vx 未満) = (2,1.0),(3,3.0),(4,5.0),(5,7.0),(6,9.0) */
  61.     /* 算出式は以下の通り */
  62.     /* eshot->vx+player->vx > 2*eshot->hx の時判定抜けが発生 */
  63.     /* player->vx の最大値は 3.0(高速移動時) */
  64.  
  65.     switch (p->type = type) {
  66.     case ESHOT_NRG01:    /* エネルギー弾(極小) */
  67.         p->hit_p = 2;    /* 速度を 1.0 未満にする事 */
  68.         p->pt = sp_eshot01 + type;
  69.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  70.         break;
  71.  
  72.     case ESHOT_NRG02:    /*    〃   (小) */
  73.     case ESHOT_NRG03:    /*    〃   (中) */
  74.     case ESHOT_NRG04:    /*    〃   (大) */
  75.         p->hit_p = 3;    /* 速度を 3.0 未満にする事 */
  76.         p->pt = sp_eshot01 + type;
  77.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  78.         break;
  79.  
  80.     case ESHOT_NRG05:    /*    〃   (特大) */
  81.     case ESHOT_NRG06:    /*    〃   (特大) */
  82.     case ESHOT_NRG22:    /*    〃   (小横に2個) */
  83.     case ESHOT_NRG32:    /*    〃   (中横に2個) */
  84.     case ESHOT_NRG23:    /*    〃   (小3角形に3個) */
  85.     case ESHOT_NRG24:    /*    〃   (小正方形に4個) */
  86.     case ESHOT_NRG14N:    /*    〃   (小斜めに4個) */
  87.     case ESHOT_NRG24N:    /*    〃   (中斜めに4個) */
  88.     case ESHOT_NRG34N:    /*    〃   (中斜めに4個) */
  89.     case ESHOT_NRG34:    /*    〃   (中正方形に4個) */
  90.     case ESHOT_NRG15:    /*    〃   (小5個) */
  91.     case ESHOT_NRG35:    /*    〃   (小と大正方形に5個) */
  92.         p->hit_p = 4;    /* 速度を 5.0 未満にする事 */
  93.         p->pt = sp_eshot01 + type;
  94.         p->info = 0x0300 | PRIORITY_ESHOT;
  95.         break;
  96.  
  97.     case ESHOT_LASER01:
  98.         p->hit_p = 3;    /* 速度を 3.0 未満にする事 */
  99.         p->pt = sp_laser01 + 8;
  100.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  101.         break;
  102.  
  103.     case ESHOT_LASEREX:
  104.         p->hit_p = 4;    /* 速度を 5.0 未満にする事 */
  105.         p->pt = sp_laser01 + 9;
  106.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  107.         break;
  108.     default:
  109.         break;
  110.     }
  111. }
  112.  
  113.  
  114.  
  115. /* 垂直同期ごとに呼ばれる */
  116. void EshotMove (void)
  117. {
  118.     ESHOT *p, *q;
  119.     signed short pl_x = player->x - 8, pl_y = player->y - 8;
  120.     signed short p_x, p_y;
  121.  
  122. #ifdef DEBUG
  123.     eshot_sum = 0;
  124. #endif
  125.     p = eshot_top;        /* 現在注目しているワーク */
  126.     q = NULL;        /* 1つ前のワーク(ワーク削除時に必要) */
  127.  
  128.     /* 弾消し中か?(高速化のためやや冗長なコードになってます) */
  129.     if (eshot_erase == 0) {
  130.         /* 通常の処理(弾消しではない) */
  131.         while (p != NULL) {
  132. #ifdef DEBUG
  133.             eshot_sum++;
  134. #endif
  135.             /* 速度を足して上位ワード(固定整数部)だけ取り出す */
  136.             p_x = p->x = (p->lx += p->vx) >> 16;
  137.             p_y = p->y = (p->ly += p->vy) >> 16;
  138.  
  139.             /* 敵弾が画面外に出たか? */
  140.             /* (画面右から出た判定と左から出た判定を1回の比較で行っている) */
  141.             if (((unsigned short) p_x > 256 + 16) || ((unsigned short) p_y > 256 + 16)) {
  142.                 if (q == NULL) {    /* リストの一番最初を削除 */
  143.                     eshot_top = p->next;
  144.                     p->next = eshot_null_top;
  145.                     eshot_null_top = p;
  146.                     q = NULL;
  147.                     p = eshot_top;
  148.                 } else {
  149.                     q->next = p->next;
  150.                     p->next = eshot_null_top;
  151.                     eshot_null_top = p;
  152.                     p = q->next;
  153.                 }
  154.             } else {
  155.                 /* 敵弾と自機の当たり判定 */
  156.                 /* この辺の最適化は -fstrings-reduce が頑張ってくれるハズ */
  157.                 signed short t, t2 = p->hit_p;
  158.                 if (((t = p_y - t2) <= pl_y)
  159.                     && ((t += (short) (t2 << 1)) >= pl_y)
  160.                     && ((t = p_x + t2) >= pl_x)
  161.                     && ((t -= (short) (t2 << 1)) <= pl_x)) {
  162.                     if (player->seq == PLAYER_SEQ_ALIVE)
  163.                         player->seq = PLAYER_SEQ_DEAD;
  164.                 } else {
  165.                     xsp_set_st (p);
  166.                 }
  167.                 q = p;
  168.                 p = p->next;
  169.             }
  170.         }
  171.     } else {
  172.         /* 弾消し中 */
  173.         char erase_flag;/* キャラクターを消す場合 =!0 */
  174.         unsigned short erase_table[14] =
  175.         {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6};
  176.  
  177.         while (p != NULL) {
  178.             if (eshot_erase > 1)
  179.                 erase_flag = 0;
  180.             else
  181.                 erase_flag = !0;
  182. #ifdef DEBUG
  183.             eshot_sum++;
  184. #endif
  185.  
  186.             /* 速度を足して上位ワード(固定整数部)だけ取り出す */
  187.             p_x = p->x = (p->lx += p->vx) >> 16;
  188.             p_y = p->y = (p->ly += p->vy) >> 16;
  189.  
  190.             /* 敵弾が画面外に出たか? */
  191.             /* (画面右から出た判定と左から出た判定を1回の比較で行っている) */
  192.             if (((unsigned short) p_x > 256 + 16) || ((unsigned short) p_y > 256 + 16)) {
  193.                 erase_flag = !0;
  194.             } else {
  195.                 p->pt = sp_eshotera + erase_table[eshot_erase];
  196.                 xsp_set_st (p);
  197.             }
  198.  
  199.             if (erase_flag) {
  200.                 if (q == NULL) {    /* リストの一番最初を削除 */
  201.                     eshot_top = p->next;
  202.                     p->next = eshot_null_top;
  203.                     eshot_null_top = p;
  204.                     q = NULL;
  205.                     p = eshot_top;
  206.                 } else {
  207.                     q->next = p->next;
  208.                     p->next = eshot_null_top;
  209.                     eshot_null_top = p;
  210.                     p = q->next;
  211.                 }
  212.             } else {
  213.                 q = p;
  214.                 p = p->next;
  215.             }
  216.         }
  217.         eshot_erase--;
  218.     }
  219. }
  220.  
  221.  
  222.  
  223. /* 敵弾消去時に呼ばれる(ゲームオーバー時) */
  224. void EshotTini (void)
  225. {
  226.     int i;
  227.  
  228.     /* リストをつなげる */
  229.     eshot_top = NULL;
  230.     eshot_null_top = eshot;
  231.     for (i = 0; i < ESHOT_MAX; i++)
  232.         eshot[i].next = &eshot[i + 1];
  233.  
  234.     eshot[ESHOT_MAX - 1].next = NULL;
  235. }
  236.